import json
import os
import random
from datetime import datetime
from pathlib import Path


from django.contrib.contenttypes.models import ContentType
from django.db.models import Q, Count
from rest_framework import filters

from apps.common.models import Pagination
from apps.data.schemas import *
from apps.system.models import User
from extensions.common.schema import *
from extensions.common.base import *
from extensions.permissions import *
from extensions.exceptions import *
from extensions.viewsets import *
from apps.pbi.filters import *
from apps.pbi.models import *
from apps.pbi.permissions import PbiPermission
from apps.pbi.serializers import *
from tools.func import get_model_fullname

def ranstr(num):
    H = 'abcdefghijklmnopqrstuvwxyz0123456789'
    H0 = 'abcdefghijklmnopqrstuvwxyz'

    salt = ''
    salt += random.choice(H0)
    for i in range(num-1):
        salt += random.choice(H)

    return salt

class PbiClientsCheckFlowViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """客户"""
    model = CheckFlow
    serializer_class = CheckFlowSerializer
    permission_classes = [IsAuthenticated, PbiPermission]
    filterset_fields = ['name']
    search_fields = ['name']
    ordering = ['id']
    # queryset = model.objects.all()
    id = ContentType.objects.get_for_model(Client).id
    queryset = CheckFlow.objects.filter(Q(model=id))


class ClientViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """客户"""
    model = Client
    serializer_class = ClientSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated, PbiPermission]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = ClientFilter
    search_fields = ['number', 'name']
    select_related_fields = ['company', 'creator','updater','next_checker']
    ordering_fields = ['id', 'number', 'name','create_time','update_time']
    ordering = ['id']
    queryset = model.objects.all()

    @transaction.atomic
    def perform_create(self,serializer):
        client = serializer.save()
        ClientCheck.objects.create(
            client=client, check_user=self.user,
            opinion=self.request.data['opinion'])
        # client.client_check.add(client_check)

    @transaction.atomic
    def perform_update(self, serializer):
        client = serializer.save()
        ClientCheck.objects.create(
            client=client, check_user=self.user,
            opinion=self.request.data['opinion'],
            is_agree=self.request.data['is_agree'])
        # client.client_check.add(client_check)

    #审核
    @action(detail=True, methods=['post'])
    def approve(self, request, pk=None):
        client = self.get_object()
        # Set the new values
        client.step = request.data.get('step', client.step)
        client.is_effective = request.data.get('is_effective', client.is_effective)
        next_checker_id = request.data.get('next_checker')
        if next_checker_id is not None:
            try:
                next_checker = User.objects.get(pk=next_checker_id)
            except User.DoesNotExist:
                return Response({"error": "User not found"}, status=status.HTTP_400_BAD_REQUEST)
            client.next_checker = next_checker

        client.save(update_fields=['step','is_effective','next_checker'])
        ClientCheck.objects.create(
            client=client, check_user=self.user,
            opinion=self.request.data['opinion'],
            is_agree=self.request.data['is_agree'])
        return Response(status=status.HTTP_204_NO_CONTENT)

    # @extend_schema(responses={200: NumberResponse})
    # @action(detail=False, methods=['get'])
    # def number(self, request, *args, **kwargs):
    #     """获取编号"""
    #     # number = Client.get_number(self.company)
    #     number = get_model_fullname(Client)
    #     return Response(data={'number': number}, status=status.HTTP_200_OK)


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def export(self, request, *args, **kwargs):
        """导出"""

        # return self.get_export_response(ClientImportExportSerializer)
        return self.get_export_response(ClientExportSerializer)

    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(ClientImportExportSerializer)

    @extend_schema(request=UploadRequest, responses={204: None})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""

        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], ClientImportExportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        client_items = import_serializer.validated_data
        number = {item['number'] for item in client_items}
        # client_set = Client.objects.filter(number__in=number, team=self.company)
        client_set = Client.objects.all()

        create_client_set = []
        update_client_set = []
        for client_item in client_items:
            # client_item['company'] = self.company
            client_item['filled_by'] = self.user
            client_item['company'] = self.user.company
            client_item['step'] = 3 #导入的数据默认填报步骤已完成
            client_item['is_effective'] = 1 #导入的数据默认为已生效
            cooperation_attribute = client_item.pop('cooperation_attribute')
            cooperation_types = client_item.pop('cooperation_types')
            for client in client_set:
                if client.number == client_item['number']:
                    c = Client.objects.update(**client_item)
                    ca = json.loads(cooperation_attribute)
                    ct = json.loads(cooperation_types)
                    c.cooperation_attribute.set(ca)
                    c.cooperation_types.set(ct)
                    update_client_set.append(client)
                    for key, value in client_item.items():
                        setattr(client, key, value)
                    break
            else:
                c=Client.objects.create(**client_item)
                ca=json.loads(cooperation_attribute)
                ct=json.loads(cooperation_types)
                c.cooperation_attribute.set(ca)
                c.cooperation_types.set(ct)

        return Response(status=status.HTTP_204_NO_CONTENT)


    @action(detail=False, methods=['get'])
    def waitMeModify(self, request, *args, **kwargs):
        """待我修改"""
        query =Q(updater=self.user) & Q(is_effective=-1) & Q(del_flag=0)
        queryset = Client.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def waitMeCheck(self, request, *args, **kwargs):
        """待我审核"""
        query =Q(next_checker=self.user) & Q(is_effective=0) & Q(del_flag=0)
        queryset = Client.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)


class ManufactorViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """厂家"""
    model = SupplierManufactor
    serializer_class = SupplierManufactorSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated, PbiPermission]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = ManufactorFilter
    search_fields = ['number', 'name', 'company__name','phone', 'contact', 'remark',
        'product_specialty__name','add_time'
                     ]
    select_related_fields = ['company', 'filled_by','next_checker']
    prefetch_related_fields = ['product_specialty','supplier_manufactor_check',]
    ordering_fields = ['id', 'number', 'name','is_effective','add_time']
    queryset = model.objects.all()

    @transaction.atomic
    def perform_create(self,serializer):
        supplier_manufactor = serializer.save()
        supplier_manufactor_check=SupplierManufactorCheck.objects.create(
            supplier_manufactor=supplier_manufactor, check_user=self.user,
            opinion=self.request.data['opinion'])
        supplier_manufactor.supplier_manufactor_check.add(supplier_manufactor_check)

    @transaction.atomic
    def perform_update(self, serializer):
        supplier_manufactor = serializer.save()
        supplier_manufactor_check = SupplierManufactorCheck.objects.create(
            supplier_manufactor=supplier_manufactor, check_user=self.user,
            opinion=self.request.data['opinion'],
            is_agree=self.request.data['is_agree'])
        supplier_manufactor.supplier_manufactor_check.add(supplier_manufactor_check)

    @extend_schema(responses={200: NumberResponse})
    @action(detail=False, methods=['get'])
    def number(self, request, *args, **kwargs):
        """获取编号"""
        # number = Client.get_number(self.company)
        number = get_model_fullname(Client)
        return Response(data={'number': number}, status=status.HTTP_200_OK)


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def export(self, request, *args, **kwargs):
        """导出"""

        # return self.get_export_response(ClientImportExportSerializer)
        return self.get_export_response(ClientExportSerializer)

    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(SupplierManufactorImportSerializer)

    @extend_schema(request=UploadRequest, responses={204: None})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""

        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], SupplierManufactorImportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        supplier_manufactor_items = import_serializer.validated_data
        supplier_manufactor_set = SupplierManufactor.objects.all()

        create_supplier_manufactor_set = []
        update_supplier_manufactor_set = []
        for supplier_manufactor_item in supplier_manufactor_items:
            supplier_manufactor_item['filled_by'] = self.user
            supplier_manufactor_item['company'] = self.user.company
            supplier_manufactor_item['step'] = 3 #导入的数据默认填报步骤已完成
            supplier_manufactor_item['is_effective'] = 1 #导入的数据默认为已生效
            product_specialty = supplier_manufactor_item.pop('product_specialty')
            for supplier_manufactor in supplier_manufactor_set:
                if supplier_manufactor.number == supplier_manufactor_item['number']:
                    s = SupplierManufactor.objects.update(**supplier_manufactor_item)
                    sp  = json.loads(product_specialty)
                    s.product_specialty.set(sp)
                    update_supplier_manufactor_set.append(supplier_manufactor)
                    for key, value in supplier_manufactor_item.items():
                        setattr(supplier_manufactor, key, value)
                    break
            else:
                s = SupplierManufactor.objects.create(**supplier_manufactor_item)
                sp = json.loads(product_specialty)
                s.product_specialty.set(sp)

        return Response(status=status.HTTP_204_NO_CONTENT)


class IntegratorViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """厂家"""
    model = SupplierIntegrator
    serializer_class = SupplierIntegratorSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated, PbiPermission]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = SupplierIntegratorFilter
    # filterset_fields = ['company', 'is_effective']
    search_fields = ['number', 'name', 'company__name','phone', 'contact', 'remark','business_scope',
        'business_qualification','add_time'
                     ]
    select_related_fields = ['company', 'filled_by', 'next_checker']
    prefetch_related_fields = ['integrators_pdfs','supplier_integrator_check']
    ordering_fields = ['id', 'number', 'name','is_effective','add_time']
    queryset = model.objects.all()

    @transaction.atomic
    def perform_create(self,serializer):
        supplier_integrator = serializer.save()
        supplier_integrator_check=SupplierIntegratorrCheck.objects.create(
            supplier_integrator=supplier_integrator, check_user=self.user,
            opinion=self.request.data['opinion'])
        supplier_integrator.supplier_integrator_check.add(supplier_integrator_check)

    @transaction.atomic
    def perform_update(self, serializer):
        supplier_integrator = serializer.save()
        supplier_integrator_check = SupplierIntegratorrCheck.objects.create(
            supplier_integrator=supplier_integrator, check_user=self.user,
            opinion=self.request.data['opinion'],
            is_agree=self.request.data['is_agree'])
        supplier_integrator.supplier_integrator_check.add(supplier_integrator_check)

    @extend_schema(responses={200: NumberResponse})
    @action(detail=False, methods=['get'])

    def number(self, request, *args, **kwargs):
        """获取编号"""
        # number = Client.get_number(self.company)
        number = get_model_fullname(Client)
        return Response(data={'number': number}, status=status.HTTP_200_OK)


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def export(self, request, *args, **kwargs):
        """导出"""

        # return self.get_export_response(ClientImportExportSerializer)
        return self.get_export_response(ClientExportSerializer)

    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(SupplierIntegratorImportSerializer)

    @extend_schema(request=UploadRequest, responses={204: None})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""

        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], SupplierIntegratorImportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        supplier_integrator_items = import_serializer.validated_data
        number = {item['number'] for item in supplier_integrator_items}
        # client_set = Client.objects.filter(number__in=number, team=self.company)
        supplier_integrator_set = SupplierIntegrator.objects.all()

        create_supplier_integrator_set = []
        update_supplier_integrator_set = []
        for supplier_integrator_item in supplier_integrator_items:
            # client_item['company'] = self.company
            supplier_integrator_item['filled_by'] = self.user
            supplier_integrator_item['company'] = self.user.company
            supplier_integrator_item['step'] = 3 #导入的数据默认填报步骤已完成
            supplier_integrator_item['is_effective'] = 1 #导入的数据默认为已生效
            for supplier_integrator in supplier_integrator_set:
                if supplier_integrator.number == supplier_integrator_item['number']:
                    update_supplier_integrator_set.append(supplier_integrator)
                    for key, value in supplier_integrator_item.items():
                        setattr(supplier_integrator, key, value)
                    break
            else:
                create_supplier_integrator_set.append(SupplierIntegrator(**supplier_integrator_item))
        else:
            try:
                SupplierIntegrator.objects.bulk_create(create_supplier_integrator_set)
                SupplierIntegrator.objects.bulk_update(update_supplier_integrator_set,
                                           SupplierIntegratorImportSerializer.Meta.fields)

            except IntegrityError:
                raise ValidationError('编号, 名称重复')

        return Response(status=status.HTTP_204_NO_CONTENT)


    @extend_schema(request=UploadPdfRequest, responses={204: None})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def upload_pdf(self, request, *args, **kwargs):
        """导入pdf数据"""

        # request_serializer = UploadPdfRequest(data=request.data)
        # request_serializer.is_valid(raise_exception=True)
        # pdf_file = request_serializer.validated_data['file']
        pdf_file = request.FILES['file']
        dest_father_dir = "supplier_integrator_pdf"
        pdf_dir = os.path.join(settings.MEDIA_ROOT, dest_father_dir)
        if not os.path.exists(pdf_dir):
            os.mkdir(pdf_dir)
        p = Path(pdf_file.name)
        pdf_pure_name = p.stem + ranstr(5)+datetime.now().strftime("%Y%m%d%H%M%S")
        pdf_extend_name = p.suffix
        pdf_name = pdf_pure_name + pdf_extend_name
        destination = open(os.path.join(pdf_dir, pdf_name), 'wb+')
        for chunk in pdf_file.chunks():
                destination.write(chunk)


        # return Response(status=status.HTTP_201_CREATED,data=pdf_name)
        return Response(status=status.HTTP_201_CREATED,data=pdf_name)



class IntegratorPdfViewSet(ModelViewSet):
    """产品图片"""

    serializer_class = IntegratorPdfSerializer
    # permission_classes = [IsAuthenticated, GoodsPermission]
    permission_classes = [IsAuthenticated]
    search_fields = ['name']
    queryset = SupplierIntegratorPdf.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)

class ProductViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """厂家"""
    model = ManufactorProduct
    serializer_class = ManufactorProductSerializer
    serializer = ManufactorProductSerializer()
    pagination_class = Pagination
    permission_classes = [IsAuthenticated, PbiPermission]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = ManufactorProductFilter
    # filterset_fields = ['company', 'is_effective']
    search_fields = ['number', 'name', 'company__name','product_model', 'product_price', 'product_specialty__name',
        'supplier_manufactor__name','add_time'
                     ]
    select_related_fields = ['company', 'filled_by','supplier_manufactor']
    prefetch_related_fields = ['product_specialty'                               ]
    ordering_fields = ['id', 'number', 'name','product_price','add_time']
    queryset = model.objects.all()


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(ManufactorProductImportSerializer)

    @extend_schema(request=UploadRequest, responses={204: None})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""
        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], ManufactorProductImportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        manufactor_product_items = import_serializer.validated_data
        manufactor_product_set = SupplierIntegrator.objects.all()

        create_manufactor_product_set = []
        update_manufactor_product_set = []
        for manufactor_product_item in manufactor_product_items:
            # client_item['company'] = self.company
            manufactor_product_item['filled_by'] = self.user
            manufactor_product_item['company'] = self.user.company
            manufactor_product_item['step'] = 3  # 导入的数据默认填报步骤已完成
            manufactor_product_item['is_effective'] = 1  # 导入的数据默认为已生效
            for manufactor_product in manufactor_product_set:
                if manufactor_product.number == manufactor_product_item['number']:
                    update_manufactor_product_set.append(manufactor_product)
                    for key, value in manufactor_product_item.items():
                        setattr(manufactor_product, key, value)
                    break
            else:
                create_manufactor_product_set.append(ManufactorProduct(**manufactor_product_item))
        else:
            try:
                ManufactorProduct.objects.bulk_create(create_manufactor_product_set)
                ManufactorProduct.objects.bulk_update(update_manufactor_product_set,
                                                       ManufactorProductImportSerializer.Meta.fields)

            except IntegrityError:
                raise ValidationError('编号, 名称重复')

        return Response(status=status.HTTP_204_NO_CONTENT)




